Service.tsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. "use client";
  2. import { ServiceTypes } from "@/api/customservice";
  3. import { getPaysApi, lredPacketApi, PayDataType, redPacketApi } from "@/api/promo";
  4. import UserRecharge, { ModalRefProps, Timeout } from "@/components/ModalPopup/RechargeModal";
  5. import RedPacketModal, { RedPacketModalProps } from "@/components/ModalPopup/RedPacketModal";
  6. import SlotsModal, { SlotModalRefProps } from "@/components/ModalPopup/SlotsModal";
  7. import WheelModal, { WheelModalProps } from "@/components/ModalPopup/WheelModal";
  8. import { getWheelApi } from "@/api/cashWheel";
  9. import { getGiveInfoApi } from "@/api/slots";
  10. import { Link } from "@/i18n/routing";
  11. import { useGlobalNoticeStore } from "@/stores/useGlobalNoticeStore";
  12. import { useSocialStore } from "@/stores/useSocials";
  13. import useWheelStore from "@/stores/useWheelStore";
  14. import { getToken } from "@/utils/Cookies";
  15. import { useRequest } from "ahooks";
  16. import { Badge } from "antd-mobile";
  17. import { useTranslations } from "next-intl";
  18. import Image from "next/image";
  19. import { FC, useEffect, useRef } from "react";
  20. interface Props {
  21. services: ServiceTypes[];
  22. socials: ServiceTypes[];
  23. }
  24. const ServiceWidget: FC<Props> = (props) => {
  25. const token = getToken();
  26. const { services, socials = [] } = props;
  27. const { wheelStatus, wheelCurrent, setWheel } = useWheelStore((state) => ({
  28. wheelStatus: state.status,
  29. wheelCurrent: state.currentWheel,
  30. setWheel: state.setWheel,
  31. }));
  32. const defaultService = services?.find((item) => item.is_suspend === 1);
  33. const newServices = services?.filter((item) => item.status === 1) || [];
  34. const setSocials = useSocialStore((state) => state.setSocials);
  35. const redPacketModalRef = useRef<RedPacketModalProps>(null);
  36. /// 首充活动ref
  37. const userRechargeRef = useRef<ModalRefProps | null>(null);
  38. // 轮盘
  39. const wheelModalRef = useRef<WheelModalProps | null>(null);
  40. const slotsRef = useRef<SlotModalRefProps | null>(null);
  41. const getWheel = () => {
  42. if (!getToken()) return Promise.resolve(undefined);
  43. return getWheelApi().then((res) => {
  44. return res.data;
  45. });
  46. };
  47. useEffect(() => {
  48. // 数据存储,侧边栏使用
  49. setSocials(socials);
  50. setWheel().then((data) => {
  51. if (data && useWheelStore.getState().status === 1) {
  52. wheelModalRef.current?.onOpen(data);
  53. }
  54. });
  55. }, []);
  56. const t = useTranslations("HomePage");
  57. const { unread, userUnred } = useGlobalNoticeStore((state) => ({
  58. unread: state.unread,
  59. userUnred: state.userUnred,
  60. }));
  61. const getRedPacketInfo = async () => {
  62. try {
  63. let redPacketInfo: any;
  64. let actList: any = [];
  65. if (token) {
  66. redPacketInfo = await lredPacketApi();
  67. actList = redPacketInfo.data?.red_packets || [];
  68. } else {
  69. redPacketInfo = await redPacketApi();
  70. actList = redPacketInfo.data || [];
  71. }
  72. // 是否有已开始但是没领过的红包
  73. return actList.filter((aItem: any) => {
  74. return aItem.can_receive && aItem.is_start && !aItem.is_receive;
  75. });
  76. } catch (error) {}
  77. };
  78. // 红包雨轮询
  79. const { data: packets, run } = useRequest<any[], any>(getRedPacketInfo, {
  80. pollingInterval: 5000,
  81. pollingErrorRetryCount: 1,
  82. pollingWhenHidden: false,
  83. });
  84. // 首充活动
  85. const getPayInfo = async (): Promise<PayDataType> => {
  86. if (token) {
  87. const result = await getPaysApi();
  88. return result.data;
  89. } else {
  90. return Promise.resolve({
  91. first_pay: [],
  92. pay: [],
  93. });
  94. }
  95. };
  96. const { data: paysInfo, run: payRun } = useRequest<PayDataType, any>(getPayInfo, {
  97. pollingErrorRetryCount: 1,
  98. pollingWhenHidden: false,
  99. });
  100. /**
  101. * 免费送活动
  102. */
  103. const getSlots = async () => {
  104. if (token) {
  105. const result = await getGiveInfoApi();
  106. return result.data;
  107. } else {
  108. return Promise.resolve({});
  109. }
  110. };
  111. const { data: slots, run: slotRun } = useRequest<any, any>(getSlots, {
  112. pollingInterval: 2000,
  113. pollingErrorRetryCount: 1,
  114. pollingWhenHidden: false,
  115. });
  116. const slotHandler = () => {
  117. slotsRef.current?.onOpen(slots);
  118. };
  119. return (
  120. <>
  121. <div
  122. className={`absolute bottom-[0.84rem] right-[0.12rem] z-50 flex w-[0.6944rem] flex-col items-center justify-center`}
  123. >
  124. {slots?.id ? (
  125. <img
  126. src={"/slots/slots-icon.gif"}
  127. className={"mb-[0.2778rem] w-[100%]"}
  128. onClick={slotHandler}
  129. />
  130. ) : null}
  131. {/*轮盘 */}
  132. {wheelStatus === 2 ? (
  133. <Link
  134. href={"/cashWheel"}
  135. className={
  136. "mb-[0.2778rem] flex h-[0.54rem] w-[0.54rem] items-center" +
  137. " justify-center rounded-[50%] bg-gradient-to-b from-[#0575e6] to-[#00f260]"
  138. }
  139. >
  140. <Image
  141. src={"/wheels/wheel-icon.gif"}
  142. alt={"wheel"}
  143. width={100}
  144. height={100}
  145. />
  146. </Link>
  147. ) : null}
  148. {/*首充*/}
  149. {paysInfo?.first_pay?.map((item, index) => {
  150. return (
  151. <div
  152. key={index}
  153. className={`mb-[0.2778rem] flex cursor-pointer flex-col items-center`}
  154. >
  155. <img
  156. className={"w-[0.54rem]"}
  157. src="/hby/recharge.png"
  158. onClick={() => {
  159. // @ts-ignore
  160. userRechargeRef.current?.onOpen(paysInfo.first_pay, index);
  161. }}
  162. />
  163. {item.end_time > 0 ? (
  164. <Timeout
  165. className={
  166. "relative before:left-0 before:top-0 before:content-['']" +
  167. " -m-[0.0417rem] before:h-[100%] before:blur-[0.0486rem]" +
  168. " before:absolute before:-z-10 before:w-[100%] before:bg-[#ed9d00]" +
  169. " text-[0.08rem]" +
  170. " z-1 text-[#fff]"
  171. }
  172. endTime={item.end_time}
  173. onEndHandler={payRun}
  174. />
  175. ) : null}
  176. </div>
  177. );
  178. })}
  179. {/* 红包雨icon */}
  180. {packets?.map((item, index) => {
  181. return (
  182. <div key={index} className={`mb-[0.2778rem] cursor-pointer`}>
  183. <img
  184. className={"w-[0.54rem] object-fill"}
  185. src="/hby/red-icon.gif"
  186. onClick={() => {
  187. redPacketModalRef.current?.onOpen(packets, index);
  188. }}
  189. />
  190. </div>
  191. );
  192. })}
  193. {/*未读消息*/}
  194. {unread || userUnred ? (
  195. <Link
  196. href={"/notification"}
  197. className={
  198. "mb-[0.2778rem] flex h-[0.54rem] w-[0.54rem] items-center" +
  199. " justify-center rounded-[50%] bg-gradient-to-t from-[#ffa111]" +
  200. " to-[#ffcf35]"
  201. }
  202. >
  203. <Badge content={userUnred + unread} style={{ "--top": "12px" }}>
  204. <i
  205. className={"iconfont icon-duanxinguanli text-[0.3rem] text-[#fff]"}
  206. ></i>
  207. </Badge>
  208. </Link>
  209. ) : null}
  210. {defaultService && (
  211. <Link
  212. href={defaultService.url}
  213. className={
  214. "flex h-[0.54rem] w-[0.54rem] items-center justify-center rounded-[50%]" +
  215. " bg-gradient-to-t from-[#ff611b] to-[#ffcf35]"
  216. }
  217. target={"_blank"}
  218. >
  219. <img
  220. className={"h-[0.3889rem] w-[0.3889rem] object-contain"}
  221. src={defaultService.icon_url}
  222. alt={""}
  223. ></img>
  224. </Link>
  225. )}
  226. </div>
  227. {/*红包雨弹窗*/}
  228. <RedPacketModal ref={redPacketModalRef} onAfterHandler={run} />
  229. {/*首充弹窗*/}
  230. <UserRecharge ref={userRechargeRef} />
  231. {/* 轮盘弹窗 */}
  232. <WheelModal ref={wheelModalRef} />
  233. {/*随机送*/}
  234. <SlotsModal ref={slotsRef} onAfterHandler={slotRun} />
  235. <div
  236. className={`grid`}
  237. style={{
  238. gridTemplateColumns: ` repeat(${newServices && newServices.length >= 5 ? 5 : (newServices?.length ?? 1)},1fr)`,
  239. }}
  240. >
  241. {newServices.map((service, index) => {
  242. return (
  243. <Link
  244. key={index}
  245. href={service.url}
  246. target={"_blank"}
  247. className="bg-white m-[0.05rem] h-[0.3889rem] w-[0.3889rem] rounded"
  248. >
  249. <img
  250. className={"h-[0.3889rem] w-[0.3889rem]"}
  251. src={service.icon_url}
  252. ></img>
  253. </Link>
  254. );
  255. })}
  256. </div>
  257. <div className={"text-[#ff6a01]"}>{t("Service")}</div>
  258. {/*share*/}
  259. <div className={"my-[0.2rem] text-[0.08rem] text-[#adadad]"}>{t("Share")}</div>
  260. <div
  261. className={`grid`}
  262. style={{
  263. gridTemplateColumns: ` repeat(${socials.length >= 5 ? 5 : socials.length},1fr)`,
  264. }}
  265. >
  266. {socials.map((service, index) => {
  267. return (
  268. <Link
  269. key={index}
  270. href={service.url}
  271. target={"_blank"}
  272. className="bg-white m-[0.05rem] h-[0.3889rem] w-[0.3889rem] rounded"
  273. >
  274. <img
  275. className={"h-[0.3889rem] w-[0.3889rem]"}
  276. src={service.icon_url}
  277. ></img>
  278. </Link>
  279. );
  280. })}
  281. </div>
  282. </>
  283. );
  284. };
  285. export default ServiceWidget;